.\"
.\" UCSD p-System cross compiler
.\" Copyright (C) 2006, 2007, 2012 Peter Miller
.\"
.\" This program is free software; you can redistribute it and/or modify
.\" it under the terms of the GNU General Public License as published by
.\" the Free Software Foundation; either version 2 of the License, or (at
.\" you option) any later version.
.\"
.\" This program is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public License along
.\" with this program. If not, see
![]() |
![]() |
expr.h | expr.c |
---|---|
typedef struct expr expr; struct expr { int e_op; union { expr *e__branch[2]; char *e__string; int e__int; double e__double; symbol *e__symbol; } e_u; }; expr *expr_alloc(int op); void expr_free(expr *ep); char *expr_text(expr *ep); int expr_is_constant(expr *ep); expr *expr_optimize(expr *ep); void expr_generate_code(expr *ep); etc etc etc #define INT_CONST 1 #define CHAR_CONST 2 #define DOUBLE_CONST 3 #define PLUS 4 #define UNARY_MINUS 5 etc etc etc #define e_branch e_u.e__branch #define e_string e_u.e__string #define e_int e_u.e__int #define e_double e_u.e__double #define e_symbol e_u.e__symbol |
#include "expr.h" expr * expr_alloc(int op) { expr *result; result = new(expr); result->e_op = op; return result; } void expr_generate_code(expr *e) { switch(e->e_op) { case PLUS: expr_generate_code(e->e_branch[0]); expr_generate_code(e->e_branch[1]); emit(OP_ADI); break; case IDENT: gen_emit_address(e->e_symbol->address); break; case INT_CONST: gen_emit_int(e->e_int); break; case DOUBLE_CONST: gen_emit_double(e->e_double); break; case CHAR_STRING: gen_emit_string(e->e_string); break; } } expression * expr_optimize(expr *e) { if (!expr_is_constant(e)) return e; switch(e->e_op) { case AND: { int n1; int n2; expr *result; n1 = expr_generate_code(e->e_branch[0]); n2 = expr_generate_code(e->e_branch[1]); result = expr_alloc(INT_CONST); result->e_int = (n1 & n2); return result; } case INT_CONST: return e; etc etc etc } } void expr_free(expr *ep) { if (!ep) return; switch(ep->e_op) { case INT_CONST: case DOUBLE_CONST: case CHAR_CONST: break; case IDENT: case CHAR_STRING: free(ep->e_string); break; case PLUS: etc etc etc expr_free(ep->e_branch[1]); /* fall through... */ case UNARY_MINUS: etc etc etc expr_free(ep->e_branch[0]); break; } free(ep); } |